package cn.alise.qdp.service.common;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import cn.alise.consts.BaseConsts;
import cn.alise.consts.ConfigConsts;
import cn.alise.enums.EnumClass;
import cn.alise.exception.ServiceException;
import cn.alise.qdp.model.wxuser.Wxuser;
import cn.alise.util.AesUtil;

/**
 * Redis操作
 */
@Service
public class RedisService {
	
	private static String AES_PASSWORD = "DPLUSMemberAesPW";
	
	@Resource
	private RedisTemplate<Object, Object> redisTemplate;
	
	/**
	 * token生成
	 * @param member
	 * @return
	 * @throws Exception 
	 */
	public String setTokenRedis(Object obj) throws Exception {
		
		Wxuser wxuser = null;
		String mobile = "";
		String parentMobile = "";
		
		wxuser = (Wxuser)obj;
		mobile = wxuser.getMobile();
		if (!StringUtils.isEmpty(wxuser.getParentMobile())) {
			parentMobile = wxuser.getParentMobile();
		}
		
		String key = mobile + BaseConsts.Redis.TOKEN;
		String token = mobile + BaseConsts.Redis.SIGN + parentMobile + BaseConsts.Redis.SIGN + UUID.randomUUID().toString().replaceAll("-", "");
		
		// 对value做AES加密
		token = AesUtil.encrypt(token, AES_PASSWORD);
		
		// 先清除原有token
		redisTemplate.delete(key);
		
		// token放入redis
//		redisTemplate.opsForValue().setIfAbsent(key, token, Duration.ofMinutes(Long.parseLong(TOKE_LIMIT)));
		redisTemplate.opsForValue().set(key, token, Long.parseLong(ConfigConsts.TOKEN_LIMIT), TimeUnit.MINUTES);
		
		return token;
	}
	
	/**
	 * 清除token
	 * @param member
	 * @return
	 * @throws Exception 
	 */
	public void clearTokenRedis(String mobile) throws Exception {
		
		String key = mobile + BaseConsts.Redis.TOKEN;
		Object token = redisTemplate.opsForValue().get(key);
		
		if (token != null) {
			redisTemplate.delete(key);
			
			Object obj = redisTemplate.opsForValue().get(token);
			
			if (obj != null) {
				redisTemplate.delete(token);
			}
		}
		
	}
	
	/**
	 * 从token获取手机号
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public String getMobileByToken(HttpServletRequest request) throws Exception {
		
		// 获取token
		String token = request.getHeader("X-Authorization");
		
		// 从redis中获取token对应的value值
		// 解析token
		String[] content = AesUtil.decrypt(token, AES_PASSWORD).split(BaseConsts.Redis.SIGN);
		
		String mobile = content[0];
		
		String parentMobile = content[1];
		
		if (StringUtils.isEmpty(parentMobile)) {
			return mobile;
		} else {
			return parentMobile;
		}
	}
	
	/**
	 * 从token获取手机号(只获取主账号)
	 * @param request
	 * @return
	 * @throws Exception
	 */
	public String getMainMobileByToken(HttpServletRequest request) throws Exception {
		
		// 获取token
		String token = request.getHeader("X-Authorization");
		
		// 从redis中获取token对应的value值
		// 解析token
		String[] content = AesUtil.decrypt(token, AES_PASSWORD).split(BaseConsts.Redis.SIGN);
		
		String mobile = content[0];
		
		return mobile;
	}
	
	/**
	 * 会员数据放入redis
	 */
	public void setMemberInfoRedis(Wxuser wxuser) {
		
		redisTemplate.opsForValue().set(wxuser.getMobile() + BaseConsts.Redis.WXUSERINFO, wxuser);
	}
	
	/**
	 * token判断
	 */
	public void judgeToken(HttpServletRequest request) throws Exception {
		
		// 获取头部token
		String token = request.getHeader("X-Authorization");
		
		if (StringUtils.isEmpty(token)) {
			throw new ServiceException(EnumClass.ResultCodeType.TOKEN_NULL.getKey(), EnumClass.ResultCodeType.TOKEN_NULL.getValue());
		}
		
		// 从token中解析拿到memberId，并在redis中通过memberId+token获取value，比对token
		// 解析token
		String content = "";
		try {
			content = AesUtil.decrypt(token, AES_PASSWORD);
		} catch (Exception e) {
			throw new ServiceException(EnumClass.ResultCodeType.TOKEN_ERROR.getKey(), EnumClass.ResultCodeType.TOKEN_ERROR.getValue());
		}
		
		String mobile = content.split(BaseConsts.Redis.SIGN)[0];
		
		Object tokenRedis = redisTemplate.opsForValue().get(mobile + BaseConsts.Redis.TOKEN);
		if (tokenRedis == null) {
			throw new ServiceException(EnumClass.ResultCodeType.TOKEN_NOTEXIST.getKey(), EnumClass.ResultCodeType.TOKEN_NOTEXIST.getValue());
			
			// token是否正确
		} else if (!token.equals(tokenRedis.toString())) {
			throw new ServiceException(EnumClass.ResultCodeType.TOKEN_ERROR.getKey(), EnumClass.ResultCodeType.TOKEN_ERROR.getValue());
			
		}
	}
}
